package nitro

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/sirupsen/logrus"
	"io/ioutil"
	"net/http"
	"net/http/cookiejar"
	"net/url"
)

type (
	Client struct {
		//Host       string
		//Token      string
		//Cookie 		string //nitroAPI调用，需要将login接口中的Cookie补充到后续接口调用中， TODO：有无自动和更优雅的机制实现
		httpClient *http.Client
		Cookies    map[string]string
	}
)

func NewClient() *Client {
	client := new(Client)
	//client.Host = host
	//client.Token = "Bearer " + token

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	cookieJar, _ := cookiejar.New(nil)
	client.httpClient = &http.Client{Transport: tr, Jar: cookieJar}
	client.Cookies = make(map[string]string)
	return client
}

func (c *Client) Login2Nitro(IP, Port string, req *LoginReq) error {

	apiUrl, _ := url.Parse("https://" + IP + ":" + Port + "/" + LoginAPI)

	requestBody := new(bytes.Buffer)

	if err := json.NewEncoder(requestBody).Encode(req); err != nil {
		logrus.WithFields(logrus.Fields{
			"API":    apiUrl.String(),
			"Params": req,
		}).Errorf("调用登录nitro接口失败, %s", err)
		return errors.New("请求参数转换失败")
	}

	request, err := http.NewRequest(http.MethodPost, apiUrl.String(), requestBody)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"API":    apiUrl.String(),
			"Params": req,
		}).Errorf("调用登录nitro接口失败, %s", err)
		return errors.New("Request拼接失败")
	}
	request.Header.Set("Content-Type", "application/json")

	resp, err := c.httpClient.Do(request)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"API":    apiUrl.String(),
			"Params": req,
		}).Errorf("调用登录nitro接口失败, %s", err)
		return errors.New("nitro接口网络异常")
	}
	defer resp.Body.Close()

	cookie := resp.Header.Get("Set-Cookie")
	c.Cookies[IP] = cookie
	fmt.Println(c.Cookies[IP])
	return nil
}

func (c *Client) GetSystemOption(IP, Port string) (*SystemOptionsResp, error) {

	apiUrl, _ := url.Parse("https://" + IP + ":" + Port + "/" + SystemOptionsAPI)

	request, err := http.NewRequest(http.MethodGet, apiUrl.String(), nil)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"API": apiUrl.String(),
		}).Errorf("调用system_options接口失败, %s", err)
		return nil, errors.New("Request拼接失败")
	}
	//request.Header.Set("Content-Type","application/json")
	request.Header.Set("Cookie", c.Cookies[IP])

	resp, err := c.httpClient.Do(request)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"API": apiUrl.String(),
		}).Errorf("调用system_options接口失败, %s", err)
		return nil, errors.New("nitro接口网络异常")
	}
	defer resp.Body.Close()

	respBytesBuf, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"API": apiUrl.String(),
		}).Errorf("调用添加设备接口失败, %s", err)
		return nil, errors.New("转换SystemOptions应答出现系统错误")
	}
	fmt.Println(string(respBytesBuf))

	result := new(SystemOptionsResp)
	if err := json.Unmarshal(respBytesBuf, result); err != nil {
		logrus.WithFields(logrus.Fields{
			"API": apiUrl.String(),
		}).Errorf("调用添加设备接口失败, %s", err)
		return nil, errors.New("转换SystemOptions应答结构出现系统错误")
	}

	fmt.Println("获取转换结果=[", result.SystemOption.ManagementIP, result.SystemOption.SerialNo, result.SystemOption.SiteName, result.SystemOption.ApplicationMode, result.SystemOption.ApplianceUptime)

	return result, nil
}

func (c *Client) GetEthernetStats(IP, Port string) error {

	apiUrl, _ := url.Parse("https://" + IP + ":" + Port + "/" + EthernetStatsAPI)

	request, err := http.NewRequest(http.MethodGet, apiUrl.String(), nil)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"API": apiUrl.String(),
		}).Errorf("调用ethernet_stats接口失败, %s", err)
		return errors.New("Request拼接失败")
	}
	//request.Header.Set("Content-Type","application/json")
	request.Header.Set("Cookie", c.Cookies[IP])

	resp, err := c.httpClient.Do(request)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"API": apiUrl.String(),
		}).Errorf("调用ethernet_stats接口失败, %s", err)
		return errors.New("nitro接口网络异常")
	}
	defer resp.Body.Close()

	respBytesBuf, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"API": apiUrl.String(),
		}).Errorf("调用添加设备接口失败, %s", err)
		return errors.New("添加设备出现系统错误")
	}
	fmt.Println(string(respBytesBuf))
	//result := new(CommonResp)
	//if err := json.Unmarshal(respBytesBuf, result); err != nil {
	//	logrus.WithFields(logrus.Fields{
	//		"API":    apiUrl.String(),
	//		"Params": req,
	//	}).Errorf("调用添加设备接口失败, %s", err)
	//	return errors.New("添加设备出现系统错误")
	//}

	return nil
}

func (c *Client) GetWanLinkUsageStats(IP, Port string) error {

	apiUrl, _ := url.Parse("https://" + IP + ":" + Port + "/" + WanLinkUsageStatsAPI)

	request, err := http.NewRequest(http.MethodGet, apiUrl.String(), nil)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"API": apiUrl.String(),
		}).Errorf("调用wan_link_usage_stats接口失败, %s", err)
		return errors.New("Request拼接失败")
	}
	//request.Header.Set("Content-Type","application/json")
	request.Header.Set("Cookie", c.Cookies[IP])

	resp, err := c.httpClient.Do(request)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"API": apiUrl.String(),
		}).Errorf("调用wan_link_usage_stats接口失败, %s", err)
		return errors.New("nitro接口网络异常")
	}
	defer resp.Body.Close()

	respBytesBuf, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"API": apiUrl.String(),
		}).Errorf("调用添加设备接口失败, %s", err)
		return errors.New("添加设备出现系统错误")
	}
	fmt.Println(string(respBytesBuf))
	//result := new(CommonResp)
	//if err := json.Unmarshal(respBytesBuf, result); err != nil {
	//	logrus.WithFields(logrus.Fields{
	//		"API":    apiUrl.String(),
	//		"Params": req,
	//	}).Errorf("调用添加设备接口失败, %s", err)
	//	return errors.New("添加设备出现系统错误")
	//}

	return nil
}
